package net.butfly.bus;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("unchecked")
public class Request implements Serializable {
	private static final long serialVersionUID = -3216119686409193334L;
	private String tx;
	private String version;
	private Object[] arguments;
	private Map<String, Object> context;

	public Request(String tx) {
		this(tx, TX.DEFAULT_VERSION, new Object[0]);
	}

	public Request(String tx, Object... arguments) {
		this(tx, TX.DEFAULT_VERSION, arguments);
	}

	public Request(String tx, String version) {
		this(tx, version, new Object[0]);
	}

	public Request(String tx, String version, Object... arguments) {
		this.tx = tx;
		this.version = version;
		this.arguments = null == arguments ? new Object[0] : arguments;
		this.context = new HashMap<String, Object>();
	}

	public Request(TX tx) {
		this(tx.value(), tx.version(), new Object[0]);
	}

	public Request(TX tx, Object... arguments) {
		this(tx.value(), tx.version(), arguments);
	}

	public String getTx() {
		return tx;
	}

	public void setTx(String tx) {
		this.tx = tx;
	}

	public String getVersion() {
		return version;
	}

	public void setVersion(String version) {
		this.version = version;
	}

	public <T> T get(String key) {
		return (T) this.context.get(key);
	}

	public <T> T put(String key, T value) {
		T result = (T) this.context.get(key);
		this.context.put(key, value);
		return result;
	}

	public int getArgumentsCount() {
		return arguments.length;
	}

	public <T> T getArgument(int index) {
		return (T) arguments[index];
	}

	public void setArgument(int index, Object value) {
		if (index >= this.arguments.length) {
			Object[] args = new Object[index - 1];
			for (int i = 0; i < index - 1; i++)
				args[i] = i < this.arguments.length ? this.arguments[i] : null;
			this.arguments = args;
		}
		this.arguments[index] = value;
	}

	public void setArguments(Object... values) {
		this.arguments = values;
	}
}
